#!/usr/bin/perl

use strict;
use XML::Simple;
use Data::Dumper;

if (@ARGV < 1) {
  die "Provide input xml";
}

my $booklist = XMLin($ARGV[0], ForceArray => ['dc:subject']);

# The hash map which accumulates the aggregate values over the catelogue.
my $author_details = {};

foreach my $book (@{$booklist->{'pgterms:etext'}}) {
  # Get only english books.
  if ($book->{'dc:language'}{'dcterms:ISO639-2'}{'rdf:value'} == 'en') {
    # Ensure that we have the author.
    if (defined $book->{'dc:creator'}) {
      my $author = $book->{'dc:creator'}{'content'};
      # We collect all topics under each encoding for a particular author.
      foreach my $sub (@{$book->{'dc:subject'}}) {
        foreach my $key (keys(%{$sub})) {
          if ($key eq 'rdf:Bag') {
            foreach my $bag_coding (@{$sub->{$key}{'rdf:li'}}) {
              foreach my $enc (keys %{$bag_coding}) {
                my $topic = $bag_coding->{$enc}{'rdf:value'};
                $author_details->{$author}{$enc}{$topic} = 1;
              }
            }
          } else {
            my $topic = $sub->{$key}{'rdf:value'};
            $author_details->{$author}{$key}{$topic} = 1;
          }
        }
      }
      # Add the number of books that the author has written.
      $author_details->{$author}{'num_books'}++;
    }
  }
}

# Print the author details collected.
print Dumper($author_details);
print "-------------------------------\n";

my $author_count_map = {};

# This loop takes care of filtering the authors by num books and
# categories written he has written.
foreach my $author (keys %{$author_details}) {
  my $count_map = {};
  my $max_count = 0;
  foreach my $enc (keys %{$author_details->{$author}}) {
    if ($enc eq 'num_books') {
      $count_map->{'num_books'} = $author_details->{$author}{'num_books'};
      next;
    }
    my $count = scalar keys(%{$author_details->{$author}{$enc}});
    if ($enc eq 'dcterms:LCC' and $max_count < $count) {
      $max_count = $count;
    }
    $count_map->{$enc} = $count;
  }
  if ($max_count > 6 and $author_details->{$author}{'num_books'} > 20) {
    $author_count_map->{$author} = $count_map;
  }
}

# A helper loop that prints the authors in sorted order of num categories
# and then number of books.
foreach my $author (
    sort {$author_count_map->{$b}{'dcterms:LCC'} <=>
    $author_count_map->{$a}{'dcterms:LCC'} ||
    $author_count_map->{$b}{'num_books'} <=>
    $author_count_map->{$a}{'num_books'}} keys %{$author_count_map}) {
  print $author . "\n";
  print Dumper($author_count_map->{$author});
}
